BITS 32

%DEFINE PL0 0
%DEFINE PL3 3
%DEFINE CODE 1
%DEFINE DATA 0
%DEFINE GDT_ACCESS(PR, PRIV, EX, DC, RW) \
	((PR<<7) | (PRIV<<5) | (1<<4) | (EX<<3) | (DC<<2) | (RW<<1) | (0))
%DEFINE GDT_FLAGS(GR, SZ) (((GR<<3) | (SZ<<2))) ; & 0x03)

; GDT_ENTRY BASE, LIMIT, ACCESS, FLAGS
%MACRO GDT_ENTRY 4
	db %2 & 0xFF	; LIMIT 0:7
	db %2 >> 8	; LIMIT 8:15
	db %1		; BASE 0:7
	db %1 >> 8	; BASE 8:15
	db %1 >> 16	; BASE 16:23
	db %3		; ACCESS BYTE
	db (%4<<4)	; FLAGS
	db %1 >> 24	; BASE 24:31
%ENDMACRO


SECTION .text
GLOBAL gdt_install
gdt_install:
	lgdt [gdtr]
	mov ax, 0x10
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov ss, ax
	jmp 0x08:flush2
flush2:
	ret


SECTION .data
ALIGN 8
gdt:
	GDT_ENTRY 0, 0, 0, 0	; NULL 
	GDT_ENTRY 0x00000000, 0xFFFFFFFF, GDT_ACCESS(1,PL0,CODE,0,1), GDT_FLAGS(1,1)
	GDT_ENTRY 0x00000000, 0xFFFFFFFF, GDT_ACCESS(1,PL0,DATA,0,1), GDT_FLAGS(1,1)
gdt_end:
gdtr:
	dw gdt_end-gdt
	dd gdt


